package net.seehope.foodie.properties;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.social.connect.web.HttpSessionSessionStrategy;
import org.springframework.social.connect.web.SessionStrategy;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.filter.OncePerRequestFilter;

import net.seehope.foodie.code.ImaValidateCode;
import net.seehope.foodie.code.ValidateCode;
import net.seehope.foodie.exception.ValidateCodeException;

//设置一个验证码过滤器，在usernamepassword过滤器之前先进行验证码过滤
public class ValidateCodeFilter extends OncePerRequestFilter{
	
	
	
	private static final Logger log = LoggerFactory.getLogger(ValidateCodeFilter.class);

	private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();
	

	private ProjectProperties properties;
	
	/*
	 * 所有当前过滤器需要拦截的路径
	 * 在初始化方法里面，从properties中取出来并放入到urls中
	 */

	private Set<String> urls = new HashSet<String>();
	/*
	 * 用来判断配置的url是否需要拦截用的
	 * matchers支持使用通配符
	 */
	
	
	private AntPathMatcher matchers = new AntPathMatcher();
	
	private AuthenticationFailureHandler failureHandler;
	
	//该方法需要手动被调用!!!!!
	@Override
	public void afterPropertiesSet() throws ServletException {
		super.afterPropertiesSet();
		
		String urlsConfig = properties.getCode().getUrls();
		String[] urlArray = StringUtils.splitByWholeSeparatorPreserveAllTokens(urlsConfig, ",");
		for (String string : urlArray) {
			urls.add(string);
		}
		
		//为什么还要添加这个呢？保证框架内部地址所需，该地址需要在拦截列表内，不能被覆盖
		urls.add("/authentication/form");
		
	}


	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		
		filterChain.doFilter(request, response);
		//boolean action = false;
		/*
		 * 迭代所有要拦截的地址，看下传入的地址是不是在urls中，在就验证，不在就放行
		 */
//		for (String string : urls) {
//			if(matchers.match(string, request.getRequestURI())) {
//				action = true;
//			}
//		}
//		
//		if(action) {
//			try {
//				validate(new ServletWebRequest(request, response));
//				filterChain.doFilter(request, response);
//			} catch (AuthenticationException e) {
//				failureHandler.onAuthenticationFailure(request, response, e);
//			}
//		}else {
//			filterChain.doFilter(request, response);
//		}
		
	}
	
//	public void validate(ServletWebRequest request) throws ServletRequestBindingException {
//		//从请求中将IMAGECODE取了出来
//		ImaValidateCode imageValidateCode =(ImaValidateCode)sessionStrategy.getAttribute(request, ProjectConstant.IMAGE_CODE_IN_SESSION);
//		
//		//从请求中将验证码取出来
//		String codeInRequest = ServletRequestUtils.getStringParameter(request.getRequest(), ProjectConstant.IMAGE_CODE_NAME);
//	
//		//接下来进行判断，先新建一个异常类
//		//1.没有访问到后台存储在sessionStrategy下的image
//		if(imageValidateCode==null) {
//			throw new ValidateCodeException("验证码不存在");			
//		}
//		if(codeInRequest==null) {
//			throw new ValidateCodeException("请填写验证码");
//		}
//		if(imageValidateCode.isExpried()) {
//			throw new ValidateCodeException("验证码已过期");
//		}
//		if(!StringUtils.equals(codeInRequest, imageValidateCode.getCode())) {
//			throw new ValidateCodeException("验证码不匹配");
//		}
//		
//		//将session中的验证码删掉
//		sessionStrategy.removeAttribute(request, ProjectConstant.IMAGE_CODE_IN_SESSION);
//	}


	public ProjectProperties getProperties() {
		return properties;
	}


	public void setProperties(ProjectProperties properties) {
		this.properties = properties;
	}


	public AuthenticationFailureHandler getFailureHandler() {
		return failureHandler;
	}


	public void setFailureHandler(AuthenticationFailureHandler failureHandler) {
		this.failureHandler = failureHandler;
	}
	
	

}
